【Salesforce】(Tips) APEXからHTTP API Callを呼ぶ/テストもする
はじめに
こんにちは植木和樹@上越妙高オフィスです。クラスメソッドでは請求管理にSalesforceを使い、請求書の出力と郵送はMoneyforward社のMFクラウド請求書を利用しています。 そしてMFクラウド請求書ではAPIを提供しています(2016年12月現在 βサービス)。
APIを用いることで取引先や請求書の作成・検索・PDFファイルを取得することができます。本日はSalesforceのAPEXコードから外部APIを呼び出す方法についてご紹介します。
コードと解説
APIのアクセス自体は簡単です。
- HttpRequestオブジェクトを作成して、メソッド、ヘッダー、URLを設定する。
- Httpオブジェクトを作成し、HttpRequestオブジェクトを引数としてsendメソッドを呼ぶ。
- HTTPResponseオブジェクトが返ってくるので適宜ステータスコードを確認し正しく実行されたかチェックする。
なお外部APIを呼び出す場合にはそのサイトを「リモートサイト」として許可しておく必要があります。
参考URL
- HttpRequest Class | Apex Developer Guide | Salesforce Developers
- HttpResponse Class | Apex Developer Guide | Salesforce Developers
HTTP Callのテスト方法
テストコードはこんな感じになります。
HTTP Callのテストは通常のテストケースに加えていくつか注意点があります。
注意点1:HttpResponseを返すMockクラスを用意する
APEXのテストコードからは実際のAPI呼出を行うことができません。そのためモッククラスを作成して擬似的にAPI呼出を行います。 モッククラスはHttpCalloutMockクラスを継承しrespondメソッドを実装すればOKです。
今回はURL(Endpoint)に応じてHttpResponseの内容を変えることで、数パターンのテストを行っています。
実装したモッククラスは Test.setMock メソッドで設定しておきましょう。
注意点2:API呼出前後でTest.startTest()/Test.startTest()を実行する
テストにあたってテストデータを用意することがありますが、テストデータ作成後にHTTP Callを行うと "You have uncommitted work pending. Please commit or rollback before calling out" というエラーが発生することがあります。SalesforceのテストではDML(insert, update, delete)が行われた後にHTTP.send()メソッドを呼ぶことができないためです。
この問題はHTTP.send()を呼ぶ前に Test.startTest() を実行することで回避可能です。
参考URL
- JP:An Introduction to Apex Code Test Methods - developer.force.com
- HttpCalloutMock インターフェースの実装による HTTP コールアウトのテスト | Apex 開発者ガイド | Salesforce Developers
まとめ
SalesforceではAPEXでHttpRequest/Http/HttpResponseといったHTTP Call用のクラスが用意されていますので、思いの外簡単に外部API呼出のコードを書くことができました。 ただ、ご紹介したようにいくつか注意点はありますので、事前に把握しておきましょう。